package com.bwie.exception;

import com.bwie.pojo.Result;
import com.bwie.pojo.StatusCode;
import com.google.common.collect.ImmutableMap;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * spring AOP的通知类 前置通知 后置通知 环绕通知
 * ControllerAdvice 所有的controller运行都会被我这个类获取到
 */
@ControllerAdvice
public class ExceptionCatch {


    //使用EXCEPTIONS存放异常类型和错误代码的映射，ImmutableMap的特点的一旦创建不可改变，并且线程安全
    private static ImmutableMap<Class<? extends Throwable>, Result> EXCEPTIONS;
    //使用builder来构建一个异常类型和错误代码的异常
    protected static ImmutableMap.Builder<Class<? extends Throwable>,Result> builder = ImmutableMap.builder();



    /**
     * 方法 需要获取到什么东西 做什么
     * 拦截自定义异常使用
     */
    @ExceptionHandler(CustomException.class)
    @ResponseBody //需要加上Json转换的注解  才能返回json格式数据
    public Result customException(CustomException e){
        return e.getResult();
    }


    /**
     * 除了自定义异常以外的异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result exception(Exception e){
        e.printStackTrace();
        //记录日志
        if(EXCEPTIONS == null)
            EXCEPTIONS = builder.build(); //构建初始化
        final Result result = EXCEPTIONS.get(e.getClass());
        if (result != null) {
            //如果匹配了异常  直接返回对应异常提示
            return result;
        } else {
            // 代表异常没有，返回统一异常码
            return new Result(99999,"出现未知异常",false);
        }
    }


    static{
        //在这里加入一些基础的异常类型判断
        builder.put(HttpMessageNotReadableException.class,new Result( StatusCode.ERROR,"非法参数",false));
        builder.put(NullPointerException.class,new Result(StatusCode.ERROR,"出现空对象异常",false));
        builder.put(IndexOutOfBoundsException.class,new Result(StatusCode.ERROR,"下角标越界异常",false));
        //自己填充的
        builder.put(ArithmeticException.class,new Result(StatusCode.ERROR,"除数不能为0",false));
    }




}
